package com.ymdd.library.permission;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.AppOpsManagerCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import com.ymdd.library.permission.target.TargetFactory;
import java.util.Arrays;
import java.util.List;

/**
 * Created by 000286 on 2017/9/22.
 * Description
 */

public final class MPermission {

  public static final int REQUEST_CODE_PERMISSION_SINGLE = 100;
  public static final int REQUEST_CODE_PERMISSION_MULTI = 101;

  public static final int REQUEST_CODE_SETTING = 300;

  private MPermission() {
  }

  public static boolean hasPermission(@NonNull Context mContext, @NonNull String... permissions) {
    return hasPermission(mContext, Arrays.asList(permissions));
  }

  public static boolean hasPermission(@NonNull Context mContext,
      @NonNull List<String> permissions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
      return true;
    }
    for (String permission : permissions) {
      String op = AppOpsManagerCompat.permissionToOp(permission);
      if (TextUtils.isEmpty(op)) {
        continue;
      }
      int result = AppOpsManagerCompat.noteProxyOp(mContext, op, mContext.getPackageName());
      if (result == AppOpsManagerCompat.MODE_IGNORED) {
        return false;
      }
      result = ContextCompat.checkSelfPermission(mContext, permission);
      if (result != PackageManager.PERMISSION_GRANTED) {
        return false;
      }
    }
    return true;
  }

  public static boolean hasAlwaysDeniedPermission(@NonNull Activity mActivity,
      @NonNull List<String> deniedPermissions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
      return false;
    }
    if (deniedPermissions.isEmpty()) {
      return false;
    }
    for (String permission : deniedPermissions) {
      boolean rationale = mActivity.shouldShowRequestPermissionRationale(permission);
      if (!rationale) {
        return true;
      }
    }
    return false;
  }

  public static boolean hasAlwaysDeniedPermission(
      @NonNull android.support.v4.app.Fragment mFragment, @NonNull List<String> deniedPermissions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;

    if (deniedPermissions.size() == 0) return false;

    for (String permission : deniedPermissions) {
      boolean rationale = mFragment.shouldShowRequestPermissionRationale(permission);
      if (!rationale) return true;
    }
    return false;
  }

  public static boolean hasAlwaysDeniedPermission(@NonNull android.app.Fragment mFragment,
      @NonNull List<String> deniedPermissions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;

    if (deniedPermissions.size() == 0) return false;

    for (String permission : deniedPermissions) {
      boolean rationale = mFragment.shouldShowRequestPermissionRationale(permission);
      if (!rationale) return true;
    }
    return false;
  }

  public static boolean hasAlwaysDeniedPermission(@NonNull Context mContext,
      @NonNull List<String> deniedPermissions) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false;

    if (deniedPermissions.size() == 0) return false;

    if (!(mContext instanceof Activity)) return false;

    for (String permission : deniedPermissions) {
      boolean rationale = ((Activity) mContext).shouldShowRequestPermissionRationale(permission);
      if (!rationale) return true;
    }
    return false;
  }

  public static @NonNull RationaleDialog rationaleDialog(@NonNull Context mContext,
      Rationale mRationale) {
    return new RationaleDialog(mContext, mRationale);
  }

  public static @NonNull SettingDialog defaultSettingDialog(@NonNull Activity mActivity,
      int mRequestCode) {
    return new SettingDialog(mActivity,
        new SettingExecutor(TargetFactory.getTarget(mActivity), mRequestCode));
  }

  public static @NonNull SettingDialog defaultSettingDialog(
      @NonNull android.support.v4.app.Fragment mFragment, int mRequestCode) {
    return new SettingDialog(mFragment.getActivity(),
        new SettingExecutor(TargetFactory.getTarget(mFragment), mRequestCode));
  }

  public static @NonNull SettingDialog defaultSettingDialog(@NonNull android.app.Fragment mFragment,
      int mRequestCode) {
    return new SettingDialog(mFragment.getActivity(),
        new SettingExecutor(TargetFactory.getTarget(mFragment), mRequestCode));
  }

  public static @NonNull SettingDialog defaultSettingDialog(@NonNull Context mContext) {
    return new SettingDialog(mContext, new SettingExecutor(TargetFactory.getTarget(mContext), 0));
  }

  public static @NonNull SettingService defineSettingDialog(@NonNull Activity mActivity,
      int mRequestCode) {
    return new SettingExecutor(TargetFactory.getTarget(mActivity), mRequestCode);
  }

  public static @NonNull SettingService defineSettingDialog(
      @NonNull android.support.v4.app.Fragment mFragment, int mRequestCode) {
    return new SettingExecutor(TargetFactory.getTarget(mFragment), mRequestCode);
  }

  public static @NonNull SettingService defineSettingDialog(@NonNull android.app.Fragment mFragment,
      int mRequestCode) {
    return new SettingExecutor(TargetFactory.getTarget(mFragment), mRequestCode);
  }

  public static @NonNull SettingService defineSettingDialog(@NonNull Context mContext) {
    return new SettingExecutor(TargetFactory.getTarget(mContext), 0);
  }

  public static @NonNull Request with(@NonNull Activity mActivity) {
    return new DefaultRequest(TargetFactory.getTarget(mActivity));
  }

  public static @NonNull Request with(@NonNull android.support.v4.app.Fragment mFragment) {
    return new DefaultRequest(TargetFactory.getTarget(mFragment));
  }

  public static @NonNull Request with(@NonNull android.app.Fragment mFragment) {
    return new DefaultRequest(TargetFactory.getTarget(mFragment));
  }

  public static @NonNull Request with(@NonNull Context mContext) {
    return new DefaultRequest(TargetFactory.getTarget(mContext));
  }
}
